﻿#ifndef __SS_NUM_ARRAY_H__
#define __SS_NUM_ARRAY_H__
#include "../ssBaseDefine.h"
#include "../dump/ssException.h"
#include <memory.h>

namespace StarSeeker
{
//此容器没有构造和析构，只能用于基本变量类型，效率比ssArray略高
//固定长度的数组
template<typename T, ulint NUM=0>
class ssNumArray
{
public:
	ssNumArray()
	{
		m_count = 0;
	}
	~ssNumArray()
	{
	}
	ssNumArray(const ssNumArray& arr)
	{
		m_count = 0;
		CopyFrom(arr);
	}
	void operator = (const ssNumArray& arr)
	{
		CopyFrom(arr);
	}
	//复制一个C数组
	void CopyFrom(const T* arr, ulint count)
	{
		if (arr)
		{
			ulint len = count < NUM ? count : NUM;
			::memcpy(m_array, arr, len*sizeof(T));
			m_count = len;
		}
	}
	//从另一个容器复制过来
	void CopyFrom(const ssNumArray& arr)
	{
		if (arr.Count()>0)
		{
			ulint len = arr.m_count < NUM ? arr.m_count : NUM;
			::memcpy(m_array, arr.m_array, len*sizeof(T));
			m_count = len;
		}
	}
	//返回当前已用个数
	ulint Count() const
	{
		return m_count;
	}
	lint Length() const
	{
		return (lint)m_count;
	}
	//返回数组最大个数
	ulint MaxCount() const
	{
		return NUM;
	}
	//返回数组地址
	const T * Memory()
	{
		return m_array;
	}
	//清空数组
	void Empty(bool zero = false)
	{
		m_count = 0;
		if (zero)
		{
			::memset(m_array, 0, sizeof(T)*NUM);
		}
	}
	//数组是否满
	bool IsFull() const
	{
		return m_count >= NUM;
	}
	//将一个元素清零
	bool SetZero(ulint offset)
	{
		if (offset < NUM)
		{
			m_array[offset] = 0;
			return true;
		}
		return false;
	}
	//和vector容器一样
	bool PushBack(const T& t)
	{
		if (m_count < NUM)
		{
			m_array[m_count++] = t;
			return true;
		}
		return false;
	}
	bool PushBackCP(const T t)
	{
		return PushBack(t);
	}
	//获取当前第一个空元素
	T * Allot()
	{
		if (m_count < NUM)
		{
			return &m_array[m_count++];
		}
		return 0;
	}
	//按下标获取元素，越界则返回0
	T * At(ulint offset)
	{
		if (offset < NUM)
		{
			return m_array + offset;
		}
		return 0;
	}
	//按下标获取元素，越界则返回内置错误元素
	T & operator [] (ulint offset) const
	{
		if (offset < NUM)
		{
			return SS_CONST_CAST(T&, m_array[offset]);
		}
		else
		{
			SS_THROW("[] out of range");
		}
	}
	//获取最后一个元素
	T * Back()
	{
		if (m_count > 0 && m_count <= NUM)
		{
			return m_array + m_count - 1;
		}
		return 0;
	}
	//获取并删除最后一个元素
	T * PopBack()
	{
		if (m_count > 0 && m_count <= NUM)
		{
			--m_count;
			return m_array + m_count;
		}
		return 0;
	}
	//设置当前已用个数
	void SetCount(ulint ct)
	{
		if (ct < NUM)
		{
			m_count = ct;
		}
		else
		{
			m_count = NUM;
		}
	}
	//删除一个元素
	void Remove(ulint offset)
	{
		if (m_count > 0 && offset < m_count)
		{
			if (offset < m_count - 1)
			{
				::memmove(m_array+offset, m_array+offset+1, (m_count - offset - 1) * sizeof(T));
			}
			--m_count;
		}
	}
	//颠倒顺序
	void ReverseOrder()
	{
		for (ulint i = 0; i < m_count / 2; ++i)
		{
			Swap(m_array[i], m_array[m_count - 1 - 0]);
		}
	}

protected:
	T				m_array[NUM];	//数组
	ulint			m_count;		//当前已用个数
};

//动态长度的数组
template<typename T>
class ssNumArray<T, 0>
{
public:
	ssNumArray()
	{
		m_pMem = 0;
		m_maxCount = 0;
		m_count = 0;
	}
	~ssNumArray()
	{
		Clear();
	}
	ssNumArray(ulint count)
	{
		m_pMem = 0;
		m_maxCount = 0;
		m_count = 0;
		Resize(count);
	}
	ssNumArray(const ssNumArray& arr)
	{
		m_pMem = 0;
		m_maxCount = 0;
		m_count = 0;
		CopyFrom(arr);
	}
	void operator = (const ssNumArray& arr)
	{
		CopyFrom(arr);
	}
    //动态创建一个数组缓存
	bool Init(ulint count)
	{
		if (!m_pMem && count > 0)
		{
			return Resize(count);
		}
		return false;
	}
	//复制一个C数组
	void CopyFrom(const T* arr, ulint count)
	{
		if (arr)
		{
			if (count <= m_maxCount)
			{
				::memcpy(m_pMem, arr, count * sizeof(T));
				m_count = count;
			}
			else if (Resize(count))
			{
				::memcpy(m_pMem, arr, count * sizeof(T));
				m_count = count;
			}
		}
	}
	//从另一个容器复制过来
	void CopyFrom(const ssNumArray& arr)
	{
		if (arr.Count() > 0)
		{
			if (arr.m_count <= m_maxCount)
			{
				::memcpy(m_pMem, arr.m_pMem, arr.m_count * sizeof(T));
				m_count = arr.m_count;
			}
			else if (Resize(arr.m_count))
			{
				::memcpy(m_pMem, arr.m_pMem, arr.m_count * sizeof(T));
				m_count = arr.m_count;
			}
		}
	}
    //从新分配大小
	bool Resize(ulint newCount)
	{
		if (newCount>m_maxCount)
		{
			T* ptemp = (T*)::malloc(newCount * sizeof(T));
			::memset(ptemp, 0, sizeof(T)*newCount);
			if (m_pMem)
			{
				if (m_count > 0)
				{
					::memcpy(ptemp, m_pMem, m_count * sizeof(T));
				}
				::free(m_pMem);
			}
			m_pMem = ptemp;
			m_maxCount = newCount;
			return true;
		}
		else if (newCount==0 && m_maxCount==0)
		{
			return Resize(8);
		}
		return false;
	}
    //释放内存
	void Clear()
	{
		if (m_pMem)
		{
			::free(m_pMem);
		}
		m_pMem = 0;
		m_maxCount = 0;
		m_count = 0;
	}
    //返回当前已用个数
	ulint Count() const
	{
		return m_count;
	}
	lint Length() const
	{
		return (lint)m_count;
	}
    //返回数组最大个数
	ulint MaxCount() const
	{
		return m_maxCount;
	}
    //返回数组地址
	const T * Memory()
	{
		return m_pMem;
	}
    //清空数组
	void Empty(bool zero=false)
	{
		m_count = 0;
		if (zero && m_pMem)
		{
			::memset(m_pMem, 0, sizeof(T)*m_maxCount);
		}
	}
    //数组是否满
	bool IsFull() const
	{
		return m_count>=m_maxCount;
	}
    //按下标获取元素，越界则返回0
	T * At(ulint offset)
	{
		if (m_pMem && offset<m_maxCount)
		{
			return m_pMem+offset;
		}
		return 0;
	}
    //获取当前第一个空元素
	T * Allot()
	{
		if (m_pMem)
		{
			if (m_count < m_maxCount)
			{
				return m_pMem[m_count++];
			}
			else if (Resize(m_maxCount * 2))
			{
				return m_pMem[m_count++];
			}
		}
		return 0;
	}
    //将一个元素清零
	bool SetZero(ulint offset)
	{
		if (m_pMem && offset<m_maxCount)
		{
			m_pMem[offset] = 0;
			return true;
		}
		return false;
	}
	//和vector容器一样
	bool PushBack(const T& t)
	{
		if (m_count < m_maxCount)
		{
			m_pMem[m_count++] = t;
			return true;
		}
		else if (Resize(m_maxCount * 2))
		{
			m_pMem[m_count++] = t;
			return true;
		}
		else
		{
			return false;
		}
	}
	bool PushBackCP(const T t)
	{
		return PushBack(t);
	}
    //按下标获取元素，越界则返回内置错误元素
	T & operator [] (ulint offset) const
	{
		if (m_pMem)
		{
			if (offset < m_maxCount)
			{
				return SS_CONST_CAST(T&, m_pMem[offset]);
			}
			else
			{
				SS_THROW("[] out of range");
			}
		}
		else
		{
			SS_THROW("[] null pointer");
		}
	}
	//获取最后一个元素
	T * Back()
	{
		if (m_count > 0 && m_count <= m_maxCount)
		{
			return m_pMem + m_count - 1;
		}
		return 0;
	}
	//获取并删除最后一个元素
	T * PopBack()
	{
		if (m_count > 0 && m_count <= m_maxCount)
		{
			--m_count;
			return m_pMem + m_count;
		}
		return 0;
	}
    //设置当前已用个数(自己管理m_count计数)
	void SetCount(ulint ct)
	{
		if (ct<m_maxCount)
		{
			m_count = ct;
		}
		else
		{
			m_count = m_maxCount;
		}
	}
	//删除一个元素
	void Remove(ulint offset)
	{
		if (m_count > 0 && offset < m_count)
		{
			if (offset < m_count - 1)
			{
				::memmove(m_pMem + offset, m_pMem + offset + 1, (m_count - offset - 1) * sizeof(T));
			}
			--m_count;
		}
	}
	//颠倒顺序
	void ReverseOrder()
	{
		for (ulint i = 0; i < m_count / 2; ++i)
		{
			Swap(m_pMem[i], m_pMem[m_count - 1 - 0]);
		}
	}

private:
	T*				m_pMem;			//数组地址
	ulint			m_maxCount;		//数组最大个数
	ulint			m_count;		//当前已用个数
};

}
#endif
